home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
AOF
/
DECAOF
/
decaof
/
io_c
< prev
next >
Wrap
Text File
|
1992-11-20
|
6KB
|
301 lines
/*
* file input/output
*
* Andy Duplain, BT Customer Systems, Brighton, UK. duplain@btcs.bt.co.uk
*/
#include <stdio.h>
#include "decaof.h"
#include "cproto.h"
#include "error.h"
#if defined(BSD42) || defined(SYSV2)
extern char *malloc P__((unsigned len));
#else
#include <malloc.h>
#endif
/*
* check for EOF or write/read errors on stream.
*/
Ferror
check_stream(fp)
FILE *fp;
{
int ret = FNOERR;
if (feof(fp))
ret = FEND;
else if (ferror(fp))
ret = FRWERR;
if (ret != FNOERR)
clearerr(fp);
return (ret);
}
/*
* read a byte from the input stream.
*/
Byte
read_byte(ifp)
FILE *ifp;
{
return ((Byte)getc(ifp));
}
/*
* read a little-endian 2-byte halfword from the input stream.
*/
Halfword
read_halfword(ifp)
FILE *ifp;
{
union {
Halfword h;
Byte b[sizeof(Halfword)];
} ret;
#if defined(LITTLE_ENDIAN)
fread((char *)&ret.h, 1, sizeof(Halfword), ifp);
#else
ret.b[HALFWORD0] = read_byte(ifp);
ret.b[HALFWORD1] = read_byte(ifp);
#endif
return (ret.h);
}
/*
* read a little-endian 4-byte word from the input stream.
*/
Word
read_word(ifp)
FILE *ifp;
{
union {
Word w;
Byte b[sizeof(Word)];
} ret;
#if defined(LITTLE_ENDIAN)
fread((char *)&ret.w, 1, sizeof(Word), ifp);
#else
ret.b[WORD0] = read_byte(ifp);
ret.b[WORD1] = read_byte(ifp);
ret.b[WORD2] = read_byte(ifp);
ret.b[WORD3] = read_byte(ifp);
#endif
return (ret.w);
}
/*
* read in the chunk header
*/
struct chunkhdr *
read_chunkhdr(ifp)
FILE *ifp;
{
static struct chunkhdr hdr;
fseek(ifp, 0L, 0);
hdr.chunkfileid = read_word(ifp);
hdr.maxchunks = read_word(ifp);
hdr.numchunks = read_word(ifp);
return (check_stream(ifp) != FRWERR ? &hdr : NULL);
}
/*
* memory pointers maintained by read_xxx functions
*/
static struct chunkent *ents = NULL; /* chunk file entries */
static char *strptr = NULL; /* string table */
static struct symbol *symptr = NULL; /* symbol table */
static char *idptr = NULL; /* identification string */
static struct aofhdr *aofhdr = NULL; /* AOF header */
/*
* free the memory used by a chunk
*/
int
free_chunk_memory(ptr)
char *ptr;
{
if (!ptr)
return (0);
if (ptr == (char *)ents) {
free(ents);
ents = NULL;
} else if (ptr == strptr) {
free(strptr);
strptr = NULL;
} else if (ptr == (char *)symptr) {
free(symptr);
symptr = NULL;
} else if (ptr == idptr) {
free(idptr);
idptr = NULL;
} else if (ptr == (char *)aofhdr) {
free(aofhdr);
aofhdr = NULL;
} else
return (-1);
return (0);
}
/*
* read in the chunk entries
*/
struct chunkent *
read_chunkents(ifp, hdr)
FILE *ifp;
struct chunkhdr *hdr;
{
register i;
if (ents)
free(ents);
ents = (struct chunkent *)malloc(
sizeof(struct chunkent) * hdr->maxchunks);
if (!ents) {
error("memory exhausted");
abort();
}
fseek(ifp, sizeof(struct chunkhdr), 0);
for (i = 0; i < hdr->numchunks; i++) {
fread(ents[i].chunkid, 1, 8, ifp);
ents[i].offset = read_word(ifp);
ents[i].size = read_word(ifp);
}
return (check_stream(ifp) != FRWERR ? ents : NULL);
}
/*
* read in the string table
*/
char *
read_stringtab(ifp, strent)
FILE *ifp;
struct chunkent *strent;
{
if (strptr)
free(strptr);
strptr = malloc(strent->size);
if (!strptr) {
error("memory exhausted");
abort();
}
fseek(ifp, strent->offset, 0);
*(Word *)strptr = read_word(ifp); /* size in 1st word */
fread(strptr + 4, 1, (int)strent->size - 4, ifp);
return (check_stream(ifp) != FRWERR ? strptr : NULL);
}
/*
* read in the symbol table
*/
struct symbol *
read_symboltab(ifp, syment, numsyms)
FILE *ifp;
struct chunkent *syment;
int numsyms;
{
register i;
if (symptr)
free(symptr);
symptr = (struct symbol *)malloc(numsyms * sizeof(struct symbol));
if (!symptr) {
error("memory exhausted");
abort();
}
fseek(ifp, syment->offset, 0);
for (i = 0; i < numsyms; i++) {
symptr[i].name = read_word(ifp);
symptr[i].flags = read_word(ifp);
symptr[i].value = read_word(ifp);
symptr[i].areaname = read_word(ifp);
}
return (check_stream(ifp) != FRWERR ? symptr : NULL);
}
/*
* read in the identification chunk
*/
char *
read_ident(ifp, ident)
FILE *ifp;
struct chunkent *ident;
{
if (idptr)
free(idptr);
idptr = malloc(ident->size);
if (!idptr) {
error("memory exhausted");
abort();
}
fseek(ifp, (long)ident->offset, 0);
fread(idptr, 1, (int)ident->size, ifp);
return (check_stream(ifp) != FRWERR ? idptr : NULL);
}
/*
* read in the AOF header
*/
struct aofhdr *
read_aofhdr(ifp, hdrent)
FILE *ifp;
struct chunkent *hdrent;
{
register i;
struct areahdr *areahdr;
if (aofhdr)
free(aofhdr);
aofhdr = (struct aofhdr *)malloc(hdrent->size);
if (!aofhdr) {
error("memory exhausted");
abort();
}
/* read-in whole of AOF header */
fseek(ifp, hdrent->offset, 0);
aofhdr->filetype = read_word(ifp);
aofhdr->version = read_word(ifp);
aofhdr->numareas = read_word(ifp);
aofhdr->numsyms = read_word(ifp);
aofhdr->entryarea = read_word(ifp);
aofhdr->entryoffset = read_word(ifp);
areahdr = (struct areahdr *)(aofhdr + sizeof(struct aofhdr));
for (i = 0; i < aofhdr->numareas; i++) {
areahdr[i].name = read_word(ifp);
areahdr[i].flags = read_word(ifp);
areahdr[i].size = read_word(ifp);
areahdr[i].numrelocs = read_word(ifp);
areahdr[i].reserved = read_word(ifp);
}
return (check_stream(ifp) != FRWERR ? aofhdr : NULL);
}
/*
* read in a relocation directive
*/
struct reloc *
read_reloc(ifp)
FILE *ifp;
{
static struct reloc reloc;
reloc.offset = read_word(ifp);
reloc.flags = read_word(ifp);
return (check_stream(ifp) != FRWERR ? &reloc : NULL);
}